#pragma once

#include "thread_pool.hpp"

void* slow(void *arg)
{
  int i = *(int*)arg;
  int a[10000];
  printf("hello world from %d\n", i);
  for (size_t i = 0; i < (1 << 18); i++)
    for (size_t j = 0; j < 10000 - 1; j++)
      a[j] = a[j + 1] * i * (a[i % 100 + a[j] % 1000] + j);
  for (size_t j = 0; j < 10000 - 1; j++)
    a[j] += a[j + 1];
  *(int*)arg = a[0];
  printf("bybye world from %d\n", i);
  return arg;
}

void* fast(void *arg)
{
  int i = *(int*)arg;
  printf("hello world from %d\n", i);
  printf("bybye world from %d\n", i);
  return NULL;
}

// few workers
// lot buffer
void test_slow1()
{
  ThreadPool pool(15, 3);
  int i = 10;

  Task task;
  task.func = slow;
  bool b;
  for (int i = 0; i < 19; i++)
  {
    task.arg = malloc (sizeof (int));
    *(int *)task.arg = i;
    b = pool.submit (task);
    printf ("submit %d is %d\n", *(int *)task.arg, b);
  }

  sleep(3);
  pool.submit (task);
  pool.shutdown();

  printf ("main off\n");
}

// lot workers
// few buffer
void test_slow2()
{
  ThreadPool pool(2, 7);
  int i = 10;

  Task task;
  task.func = slow;
  bool b;
  for (int i = 0; i < 19; i++)
  {
    task.arg = malloc (sizeof (int));
    *(int *)task.arg = i;
    b = pool.submit (task);
    printf ("submit %d is %d\n", *(int *)task.arg, b);
  }

  sleep(3);
  b = pool.submit (task);
  printf ("submit %d is %d\n", *(int *)task.arg, b);
  pool.shutdown();

  printf ("main off\n");
}

// lot workers
// lot buffer
void test_slow3()
{
  ThreadPool pool(12, 7);
  int i = 10;

  Task task;
  task.func = slow;
  bool b;
  for (int i = 0; i < 29; i++)
  {
    task.arg = malloc (sizeof (int));
    *(int *)task.arg = i;
    b = pool.submit (task);
    printf ("submit %d is %d\n", *(int *)task.arg, b);
  }

  sleep(3);
  b = pool.submit (task);
  printf ("submit %d is %d\n", *(int *)task.arg, b);
  pool.shutdown();

  printf ("main off\n");
}

void test_fast1()
{
  ThreadPool pool(15, 3);
  int i = 10;

  Task task;
  task.func = fast;
  bool b;
  for (int i = 0; i < 19; i++)
  {
    task.arg = malloc (sizeof (int));
    *(int *)task.arg = i;
    b = pool.submit (task);
    printf ("submit %d is %d\n", *(int *)task.arg, b);
  }

  sleep(3);
  pool.submit (task);
  pool.shutdown();

  printf ("main off\n");
}

void test_misc1()
{
  ThreadPool pool(4, 3);
  int i = 10;

  Task task;
  
  bool b;
  for (int i = 0; i < 9; i++)
  {
    task.arg = malloc (sizeof (int));
    if (i % 2)
      task.func = fast;
    else
      task.func = slow;
    *(int *)task.arg = i;
    b = pool.submit (task);
    printf ("submit %s to %d is %d\n", (i % 2 ? "fast" : "slow"), *(int *)task.arg, b);
  }

  sleep(3);
  pool.shutdown();

  printf ("main off\n");
}
